package com.collins.reflections;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

public class ReflectionTest {

    public static void main(String[] args) {
        // testClass();
        // testConstructor();
        testField();
    }

    public static void testClass() {
        try {
            // TODO method 1
            Class<?> clazz = Class.forName("com.collins.reflections.Student");
            System.out.println(clazz.getName());
            System.out.println(clazz.getSuperclass());
            System.out.println(clazz.getSimpleName());
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        System.out.println("=====================\r\n" +
                "[from class]");
        // TODO method 2
        String name = Student.class.getName();
        System.out.println(name);
        System.out.println("=====================\r\n" +
                "[from instance]");
        // TODO method 3
        Student s = new Student();
        String name1 = s.getClass().getName();
        System.out.println(name1);
    }

    public static void testConstructor() {
        Class<Student> s = Student.class;
        System.out.println("[recursion all]");
        Constructor<?>[] constructors = s.getConstructors();
        for (Constructor<?> constructor : constructors) {
            printConstructor(constructor);
        }
        try {
            System.out.println("[single out with parameters]");
            Constructor c1 = s.getConstructor();
            printConstructor(c1);
            Constructor<Student> c2 = s.getConstructor(String.class);
            printConstructor(c2);
            System.out.println("create new instance with no arg constructor:");
            Student s1 = (Student) c1.newInstance();
            System.out.println(s1);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public static void testField() {
        Class<Student> s = Student.class;
        System.out.println("[recursion all]");
        Field[] fields = s.getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getType() + " " + field.getName());
        }
        System.out.println("[single out with name]");
        try {
            Field name = s.getDeclaredField("name");
            System.out.println(name.getType() + " " + name.getName());
        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        }
    }

    public static void printConstructor(Constructor<?> constructor) {
        System.out.println(constructor.getName() + " ==> "
                + constructor.getParameterTypes().length
                + " parameters:"
                + Arrays.toString(constructor.getParameterTypes()));
    }
}
